package v3;

import java.io.*;

import java.util.ArrayList;

import java.io.IOException;


import Kernel.Client;
import Kernel.Vehicule;
import Kernel.Ville;
import Kernel.Serveur;
import Kernel.Trajet;
import Kernel.Billet;

import java.beans.XMLEncoder;
import java.beans.XMLDecoder;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;

/**
 * Cette classe permet de sérialiser les données du serveur en utilisant un XMLencoder
 * @author benaicha
 *
 */

public class Sauvegarde1 {
	
	
	/**
	 * Constructeur de la classe sauvegarde qui est un constructeur vide mais necessaire
	 */
	private Sauvegarde1() {}
	
	/**
	 * cette fonction encodeToFile permet de sauvegarder les données, instances d'un object vers un fichier XML
	 * Ici on met en paramètre un serveur, avec lequel on va sauvegarder trois type de données, les données concernant les objects de type trajet,
	 * les objets de type Ville, les objets de type Vehicule,
	 * Un serveur possède une ArrayList de chaque type de donné, on parcour donc les ArrayLists et pour chaque objet on applique la sauvegarde 
	 * @param serveur
	 * @param fileName
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static void encodeToFile(Serveur serveur,String fileName) throws FileNotFoundException, IOException {
        // ouverture de l'encodeur vers le fichier
        XMLEncoder encoder = new XMLEncoder(new FileOutputStream(fileName));
        try {
            // serialisation des l'objets
        	int i;
        	int nombreDeTrajet= serveur.getTrajets().size(); // on récupere le nombre de trajets qui servira pour la deserialisation
        	int nombreDeVille= serveur.getVilles().size();
        	int nombreDeVehicule= serveur.getVilles().size();
        	int nombreDeBillet= serveur.getBillets().size();
        	int nombreDeClient= serveur.getClients().size();
        	
        	// le nombre de trajets, villes et vehicules sont enregistrées au sein du fichier xml,
        	// pour pouvoir les récupérés et s'en servir pour la deserialisation 
        	encoder.writeObject(nombreDeTrajet);
			encoder.flush();
			
			encoder.writeObject(nombreDeVille);
			encoder.flush();
			
			encoder.writeObject(nombreDeVehicule);
			encoder.flush();
			
			
			encoder.writeObject(nombreDeBillet);
			encoder.flush();
			
			encoder.writeObject(nombreDeClient);
			encoder.flush();
        	
			// on serialise tout les object de type trajet vers le fichier xml
    		for(i=0; i < serveur.getTrajets().size();i++){
    			encoder.writeObject(serveur.getTrajets().get(i));
    			encoder.flush();
    		}
    		
    		// on serialise tout les objects de type ville vers le ficier xml
    		for(int j=0; j< serveur.getVilles().size();j++){
    			encoder.writeObject(serveur.getVilles().get(j));
    			encoder.flush();
    		}
    	
    		// on serialise tout les object de type vehicule  vers le fichier xml
    		for(int k=0;k< serveur.getVehicules().size();k++){
    			encoder.writeObject(serveur.getVehicules().get(k));
    			encoder.flush();
    		}
    		
    		// on serialise tout les objets de type billet vers le fichier xml
    		for(int l=0;l<serveur.getBillets().size();l++){
    			encoder.writeObject(serveur.getBillets().get(l));
    			encoder.flush();
    		}
    		
    		// on serialise tout les objets de type Clients vers le fichier xml
    		for(int m=0;m<serveur.getClients().size();m++){
    			encoder.writeObject(serveur.getClients().get(m));
    			encoder.flush();
    		}
    		
        } finally {
            // fermeture de l'encodeur
            encoder.close();
        }
    }
	
	
	/**
	 * Cette méthode permet de recupéré un serveur avec les données que l'on à sauvegardé précédament
	 * on lui fournie en paramètre un nom de fichier qui contient toutes les données du XML 
	 * @param fileName
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static Serveur decodeFromFile(String fileName) throws FileNotFoundException, IOException {
	    Serveur s1 = new Serveur();
	    ArrayList<Trajet> trajet= new ArrayList<Trajet>();
	    ArrayList<Ville> ville= new ArrayList<Ville>();
	    ArrayList<Vehicule> vehicule = new ArrayList<Vehicule>();
	    ArrayList<Billet> billet= new ArrayList<Billet>();
	    ArrayList<Client> client= new ArrayList<Client>();
	    int nombreDeTrajet;
	    int nombreDeVille;
	    int nombreDeVehicule;
	    int nombreDeBillet;
	    int nombreDeClient;
	    
	    // ouverture de decodeur
	    XMLDecoder decoder = new XMLDecoder(new FileInputStream(fileName));
	    try {
	        
	    	nombreDeTrajet = (Integer)decoder.readObject(); // on récupere le nombre d'element de type Trajet contenue dans le XML
	    													// pour savoir jusqu'à combien d'elements il faut ajouter dans l'ArrayLIst<Trajet>
	    	nombreDeVille = (Integer)decoder.readObject();  // il faut caster l'element object en un object Integer
	    													//pour pouvoir l'affecter à un int car l'affectation d'un object vers un int ne peut pas se faire 
	    	nombreDeVehicule = (Integer)decoder.readObject();
	    	
	    	nombreDeBillet = (Integer)decoder.readObject();
	    	
	    	nombreDeClient = (Integer)decoder.readObject();
	    	
	    	// deserialisation des l'objets de type trajet 
	    	for(int i=0;i<nombreDeTrajet;i++){
	    		trajet.add((Trajet)decoder.readObject());
	    	}
	    	
	    	// deserialisation des objects de type Ville
	    	for(int j=0;j<nombreDeVille;j++){
	    		ville.add((Ville)decoder.readObject());
	    	}
	    	
	    	// deserialisation des objects de type vehicule
	    	for( int k=0; k<nombreDeVehicule;k++){
	    		vehicule.add((Vehicule)decoder.readObject());
	    	}
	    	
	    	//deserialisation des objets de type vehicule
	    	for(int l=0; l<nombreDeBillet;l++){
	    		billet.add((Billet)decoder.readObject());
	    	}
	    	
	    	//deserialisation des objets de type client
	    	for(int l=0; l<nombreDeClient;l++){
	    		client.add((Client)decoder.readObject());
	    	}
	    	
	    	// on affecte les arrayLists récupérées au serveur 
	    	s1.setVehicules(vehicule);
	    	s1.setVilles(ville);
	    	s1.setTrajets(trajet);
	    	s1.setBillets(billet);
	    	s1.setClients(client);
	    	
	    } finally {
	        // fermeture du decodeur
	        decoder.close();
	    }
	    return s1;
	}
	
	
	/*      
	 * declaration
	 * private static final Sauvegarde1 XMLTools = null;
	 * 
	 * chargement
	 * try {
	 			Serveur serv = new Serveur();
			 	serv = (Serveur) XMLTools.decodeFromFile("Sauvegarde-Serveur.xml");
	           
	        } catch(Exception e) {
	            e.printStackTrace();
	        }
	 *
	 *sauvegarde
	 *try {
            Sauvegarde1.encodeToFile(serv,"Sauvegarde-Serveur.xml");
           
        } catch(Exception e) {
            e.printStackTrace();
        }
	 */
	 
}
